<template>
  <el-card>
    <div style="margin-bottom: 10px">
      <el-cascader
        ref="cascader"
        v-model="zone"
        :options="zones"
        :props="{ expandTrigger: 'hover', emitPath: false, checkStrictly: true }"
        @change="onZoneChange"
        placeholder="选择分区"
        style="width: 180px"
      >
      </el-cascader>
    </div>
    <div ref="chart" style="height: 600px"></div>
  </el-card>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import * as echarts from 'echarts'
import { useApi } from '@/composables/useApi'
import partitionData from '@/assets/partition.json'

const http = useApi()

const chart = ref(null)
const cascader = ref(null)
let myChart = null
let timer = null

// 分区列表（value为tid，需与后端一致）
const zones = partitionData
const zone = ref(0) // 默认选中全站

// 指标配置
const metrics = [
  { key: 'view', name: '播放量' },
  { key: 'danmaku', name: '弹幕数' },
  { key: 'reply', name: '评论数' },
  { key: 'like', name: '点赞数' },
  { key: 'coin', name: '投币数' },
  { key: 'favorite', name: '收藏数' },
  { key: 'count', name: '视频数' },
]

// 后端数据缓存
let allData = {}

// 更精细的指标分组，每组单独Y轴
const yAxisGroups = [
  { indices: [0], name: '播放量', color: '#337ab7' }, // 播放量
  { indices: [1], name: '弹幕数', color: '#5cb85c' }, // 单独弹幕
  { indices: [2], name: '评论数', color: '#f0ad4e' }, // 单独评论
  { indices: [3, 4, 5], name: '三连量', color: '#d9534f' }, // 点赞、投币、收藏
  { indices: [6], name: '视频数', color: '#fb7299' }, // 单独视频数
]

function renderChart(currentStep = null) {
  const data = allData[zone.value] || []
  const months = data.map((item) => item.month)

  // 处理动画步骤 - 如果指定了步骤，只显示到该步骤的数据
  const displayData = currentStep ? data.slice(0, currentStep) : data
  const displayMonths = currentStep ? months.slice(0, currentStep) : months

  // 计算每组数据的最大值，用于优化坐标轴范围
  const groupMaxValues = yAxisGroups.map((group) => {
    return Math.max(
      ...group.indices.flatMap((idx) => {
        const metricKey = metrics[idx].key
        return displayData.map((item) => item[metricKey])
      }),
    )
  })

  const option = {
    title: {
      text: `${cascader.value.getCheckedNodes()[0].label}分区月度数据`,
      left: 'center',
      top: 10,
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
      },
    },
    legend: {
      data: metrics.map((m) => m.name),
      // 固定图例位置在顶部，与第二个文件保持一致
      top: 40,
      left: 'center',
      width: '90%',
      // 强制图例水平排列并自动换行
      type: 'scroll',
      orient: 'horizontal',
      padding: [5, 0],
      itemGap: 15,
      pageButtonItemGap: 5,
      pageButtonGap: 10,
    },
    grid: {
      // 增加顶部距离避免图例与图表重叠
      top: '18%',
      left: '8%',
      right: '18%',
      bottom: '5%',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      data: displayMonths,
      boundaryGap: true,
    },
    yAxis: yAxisGroups.map((group, index) => {
      // 动态计算坐标轴最大值，留10%余量使趋势更明显
      const maxVal = groupMaxValues[index]
      const axisMax = maxVal > 0 ? Math.ceil(maxVal * 1.1) : 100

      return {
        type: 'value',
        name: group.name,
        position: index === 0 ? 'left' : 'right',
        offset: index > 1 ? (index - 1) * 80 : 0, // 右侧轴偏移，避免重叠
        axisLine: { lineStyle: { color: group.color } },
        axisLabel: {
          formatter: (value) => {
            if (value >= 10000) return (value / 10000).toFixed(1) + '万'
            if (value >= 1000) return (value / 1000).toFixed(1) + 'k'
            return value
          },
        },
        max: axisMax, // 设置坐标轴最大值
        splitLine: { show: index === 0 }, // 只显示第一个Y轴的网格线
      }
    }),
    series: metrics.map((metric, metricIndex) => {
      // 找到当前指标所属的Y轴组
      const yAxisIndex = yAxisGroups.findIndex((group) => group.indices.includes(metricIndex))

      return {
        name: metric.name,
        type: metric.name === '视频数' ? 'bar' : 'line',
        data: displayData.map((item) => item[metric.key]),
        smooth: true,
        yAxisIndex,
        lineStyle: { width: 2.5 },
        itemStyle: { radius: 4 },
        emphasis: {
          scale: true,
          itemStyle: { shadowBlur: 10 },
        },
        // 为柱状图添加更多视觉效果
        ...(metric.name === '视频数' && {
          itemStyle: {
            color: yAxisGroups[yAxisIndex].color,
            borderRadius: [4, 4, 0, 0],
          },
        }),
      }
    }),
    animation: true,
    animationDuration: 800, // 动画时长
  }

  myChart.setOption(option, true) // 第二个参数 true，强制动画
}

function playAnimation() {
  const data = allData[zone.value] || []
  const months = data.map((item) => item.month)
  let currentStep = 1
  clearInterval(timer)

  // 如果数据较少，调整动画速度
  const intervalTime = 20

  timer = setInterval(() => {
    if (currentStep <= months.length) {
      renderChart(currentStep)
      currentStep++
    } else {
      clearInterval(timer)
    }
  }, intervalTime)
}

async function loadData() {
  const { data: res } = await http.get('/video/getDataMonthly', { params: { tid: zone.value } })
  if (res) {
    allData[zone.value] = res
    console.log('后端数据', res)
  } else {
    allData[zone.value] = []
    console.log('后端数据为空或格式不对', res)
  }
  playAnimation()
}

function onZoneChange() {
  if (myChart) {
    myChart.clear()
  }
  if (allData[zone.value]) {
    playAnimation()
  } else {
    loadData()
  }
}

onMounted(() => {
  myChart = echarts.init(chart.value)
  loadData()

  // 响应窗口大小变化
  const handleResize = () => {
    if (myChart) {
      myChart.resize()
    }
  }

  window.addEventListener('resize', handleResize)

  // 组件卸载时清理
  return () => {
    window.removeEventListener('resize', handleResize)
    if (timer) {
      clearInterval(timer)
    }
    if (myChart) {
      myChart.dispose()
    }
  }
})

// 监听数据变化，确保图表正确渲染
watch(
  () => allData[zone.value],
  () => {
    if (myChart) {
      playAnimation()
    }
  },
)
</script>
